﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using COM.Web;
using WebApp.Service;
using System.IO;

namespace WebApp.Web.Service
{
    public interface IUploadFileService
    {
        Guid UploadFile(string fileCategory, string fileName, HttpPostedFileBase postFile);
        string GetFile(Guid fileItemID);
        /// <summary>
        /// 读取文件信息
        /// </summary>
        /// <param name="fileItemID"></param>
        /// <returns>物理文件相对路径(如:Upload/2015/4/a.jpg),逻辑文件名称,文件大小,下载次数</returns>
        Tuple<string, string, long,int> GetFileInfoByID(Guid fileItemID);
        string GetPicture(Guid fileItemID, int width, int height);
        Guid SavePicture(System.Drawing.Image img, string sourceFileName);
    }

    public class UploadFileService : IUploadFileService
    {
        private IFileItemService fileItemService;
        private IWebAppPathService webAppPathService;
        public UploadFileService(IWebAppPathService webAppPathService, IFileItemService fileItemService)
        {
            this.webAppPathService = webAppPathService;
            this.fileItemService = fileItemService;
        }

        private string GetUploadPath(string fileCategory)
        {
            var path = this.webAppPathService.UploadFilePath;
            path = Path.Combine(path, fileCategory);
            if (!Directory.Exists(path))
                Directory.CreateDirectory(path);
            path = Path.Combine(path, DateTime.Today.Year.ToString());
            if (!Directory.Exists(path))
                Directory.CreateDirectory(path);
            path = Path.Combine(path, DateTime.Today.Month.ToString());
            if (!Directory.Exists(path))
                Directory.CreateDirectory(path);
            return path;
        }


        public Guid UploadFile(string fileCategory, string fileName, HttpPostedFileBase postFile)
        {
            var path = this.GetUploadPath(fileCategory);
            var fileID = Guid.NewGuid();
            var uploadFilePath = Path.Combine(path, fileID + Path.GetExtension(fileName));
            postFile.SaveAs(uploadFilePath);
            var fileInfo = new System.IO.FileInfo(uploadFilePath);
            var fileUrl = uploadFilePath.Substring(this.webAppPathService.AppDataPath.Length).Replace('\\', '/').TrimStart('/');
            var filePath = string.Format("file://{0}", fileUrl);
            this.fileItemService.Create(filePath, fileName, fileInfo.Length);
            return fileID;
        }

        public Guid SavePicture(System.Drawing.Image img, string sourceFileName)
        {
            var path = this.GetUploadPath("Picture");
            var fileItemID = Guid.NewGuid();
            var uploadFilePath = Path.Combine(path, fileItemID + ".jpg");
            img.Save(uploadFilePath);
            var fileInfo = new System.IO.FileInfo(uploadFilePath);
            var fileUrl = uploadFilePath.Substring(this.webAppPathService.AppDataPath.Length).Replace('\\', '/').TrimStart('/');
            var filePath = string.Format("file://{0}", fileUrl);
            this.fileItemService.Create(filePath, sourceFileName, fileInfo.Length);
            return fileItemID;
        }

        public string GetFile(Guid fileItemID)
        {
            var fileItem = this.fileItemService.GetFileItemID(fileItemID);
            if (fileItem == null)
                throw new ApplicationException(string.Format("服务端文件{0}不存在.", fileItemID));

            var filePath = fileItem.FilePath.TrimOrEmpty().Substring("file://".Length);
            filePath = Path.Combine(this.webAppPathService.AppDataPath, filePath);
            if (!File.Exists(filePath))
                throw new ApplicationException(string.Format("服务端文件{0}不存在.", filePath));

            return filePath;
        }

        public Tuple<string,string,long,int> GetFileInfoByID(Guid fileItemID)
        {
            var fileItem = this.fileItemService.GetFileItemID(fileItemID);
            if (fileItem == null)
                throw new ApplicationException(string.Format("服务端文件{0}不存在.", fileItemID));

            var filePath = fileItem.FilePath.TrimOrEmpty().Substring("file://".Length);
            filePath = Path.Combine(this.webAppPathService.AppDataPath, filePath);
            if (!File.Exists(filePath))
                throw new ApplicationException(string.Format("服务端文件{0}不存在.", filePath));

            return new Tuple<string,string,long,int>(filePath,fileItem.FileName,fileItem.FileSize,fileItem.DownloadCount);
        }

        
        public string GetPicture(Guid fileItemID, int width, int height)
        {
            var fileItem = this.fileItemService.GetFileItemID(fileItemID);
            if (fileItem == null)
                throw new ApplicationException(string.Format("服务端文件{0}不存在.", fileItemID));

            var fileItemPath = fileItem.FilePath.TrimOrEmpty().Substring("file://".Length);
            var localFilePath = this.GetLocalFilePath(fileItemPath);
            //如果是调整后保存在本地的文件,是通过 SavePicture() 保存的,那么直接返回,不需要再调整大小
            var fileItemName = Path.GetFileNameWithoutExtension(fileItem.FileName.TrimOrEmpty());
            var s = fileItemName.Split('_');
            if (s.Count() == 3)
            {
                if (s[1] == width.ToString() && s[2] == height.ToString())
                {
                    return localFilePath;
                }
            }

            var cacheFile = this.GetCacheFileName(fileItemPath, width, height);
            if (File.Exists(cacheFile))
                return cacheFile;

            //创建缓存文件

            var pictureService = Unity.Instance.GetService<IImageService>();
            var img = System.Drawing.Image.FromFile(localFilePath);
            if (img.Width == width && img.Height == height)
            {
                return localFilePath;  //小概率事件
            }
            else
            {
                var resizeImg = pictureService.ResizePicture(img, width, height);
                //var stream = new MemoryStream();
                //resizeImg.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
                //stream.Position = 0;
                resizeImg.Save(cacheFile);
                return cacheFile;
            }
        }

        private string GetLocalFilePath(string fileItemPath)
        {
            var localFilePath = Path.Combine(this.webAppPathService.AppDataPath, fileItemPath);
            if (!File.Exists(localFilePath))
                throw new ApplicationException(string.Format("服务端文件{0}不存在.", localFilePath));

            return localFilePath;
        }

        private string GetCacheFileName(string filePath, int width, int height)
        {
            var cacheFilePath = this.GetCacheFilePath(filePath, width, height);
            var fileName = Path.GetFileNameWithoutExtension(filePath);
            var file = Path.Combine(cacheFilePath, fileName + ".jpg");
            return file;
        }

        private string GetCacheFilePath(string filePath, int width, int height)
        {
            var path = Path.Combine(this.webAppPathService.AppDataPath, "Cache");
            if (!Directory.Exists(path))
                Directory.CreateDirectory(path);
            var wh = string.Format("{0}_{1}", width, height);
            path = Path.Combine(path, wh);
            if (!Directory.Exists(path))
                Directory.CreateDirectory(path);
            var plist = Path.GetDirectoryName(filePath).Split('/').ToList();
            foreach (var p in plist)
            {
                path = Path.Combine(path, p);
                if (!Directory.Exists(path))
                    Directory.CreateDirectory(path);
            }

            return path;
        }

    }
}